"""
Alpha Manager 
Entidades de la base de datos
"""

import transaction
import cryptacular.bcrypt
from pyramid.security import Allow
from pyramid.security import Everyone
from pyramid.security import Authenticated
from sqlalchemy import Table
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relation
from sqlalchemy.orm import backref
from sqlalchemy.orm import column_property
from sqlalchemy.orm import synonym
from sqlalchemy.orm import joinedload
from sqlalchemy.types import Integer
from sqlalchemy.types import Unicode
from sqlalchemy.types import UnicodeText
from sqlalchemy.sql import func
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session
from sqlalchemy.orm import sessionmaker
from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
from alpha.modelos import Base


crypt = cryptacular.bcrypt.BCRYPTPasswordManager()

def hash_password(password):
    return unicode(crypt.encode(password))


"""
Tablas de la base de datos
"""

"""
Tablas Usuario: almacena los datos referentes a los usuario
"""

class Usuario(Base):
    __tablename__ = 'usuario'	
    id_usuario = Column(Integer, primary_key=True)
    nombreUsuario = Column(Unicode(20), unique=True)
    _password = Column('password', Unicode(60))
    nombre = Column(Unicode(50))
    apellido = Column(Unicode(50))
    telefono = Column(Integer)
    nroDocumento = Column(Integer)
    mail = Column(Unicode(50))

    def __init__(self, nombreUsuario, password, nombre, mail):
        self.nombreUsuario = nombreUsuario
        self.nombre = nombre
        self.mail = mail
        self.password = password
        
    def _get_password(self):
        return self._password

    def _set_password(self, password):
        self._password = hash_password(password)
		
    password = property(_get_password, _set_password)
    password = synonym('_password', descriptor=password)
 
    @classmethod
    def get_by_username(cls, nombreUsuario):
        return DBSession.query(cls).filter(cls.nombreUsuario == nombreUsuario).first()

    @classmethod
    def check_password(cls, nombreUsuario, password):
        usuario = cls.get_by_username(nombreUsuario)
        if not usuario:
            return False
        return crypt.check(usuario.password, password)
        
"""
Seccion que inicializa la base de datos
"""

def initialize_sql(engine):
    DBSession.configure(bind=engine)
    Base.metadata.bind = engine
    Base.metadata.create_all(engine)
    try:
        transaction.begin()
        session = DBSession()
        usuario1 = Usuario('administrador', 'admin2012', 'Administrador', 'admin@gmail.com')
        usuario2 = Usuario('liderProyecto', 'proyecto2012', 'Lider de Proyecto', 'proyecto@gmail.com')
        usuario3 = Usuario('liderFase', 'fase2012', 'Lider de Fase', 'fase@gmail.com')
        usuario4 = Usuario('desarrollador', 'desarrollo2012', 'Desarrollador', 'desarrollo@gmail.com')

        session.add(usuario1)
        session.add(usuario2)
        session.add(usuario3)
        session.add(usuario4)
        transaction.commit()
    except IntegrityError:
        # already created
        transaction.abort()


"""
Clase RootFactory para los permisos
"""

class RootFactory(object):
    __acl__ = [ (Allow, Everyone, 'view'),
                (Allow, Authenticated, 'edit') ]


    def __init__(self, request):
        pass
